const {Sequelize, Model, Op} = require('sequelize');

const sequelize = new Sequelize(config.mysql.db_name, config.mysql.user, config.mysql.password, {
  dialect: 'mysql'
  , host: config.mysql.host
  , port: config.mysql.port
  , timezone: '+08:00' // 自动生成的时间相关字段用北京时间记录
  , define: {
    // timestamps:false // ← 不会再自动生成 createdAt 和 updatedAt
    paranoid: true // ← 自动维护软删除字段 deletedAt
    // ,underscored:true // 数据库中的字段名使用下划线而非驼峰命名,注意这里指的是字段,而不是表名,mysql中表名一定是小写的,即使你通过sequelize定义时是使用的驼峰
  }
});

/** 统一处理返回给客户端的字段 */
// Model.prototype.toJSON = function () {
//   return
// }

/**
 * 按页码关联查询
 * @param page_number
 * @param order_by
 * @param query_obj
 * @param filter
 * @param page_size
 * @param include
 * @param attributes
 * @return {Promise<{page_number, count: ((label?: string) => void) | number | ((options: CountWithOptions) => Promise<{[p: string]: number}>) | ((options?: CountOptions) => Promise<number>) | string | ((key?: (IDBValidKey | IDBKeyRange)) => IDBRequest<number>), total_page: number, rows: any}>}
 */
Model.findListByPageNumber = async function ({
    page_number = 1
    , order_by = [['createdAt', 'DESC']]
    , query_obj = {} // whereObj(like)
    , filter = {} // whereObj 非like
    , page_size = config.page_size
    , include = [{all: true, nested: true, required: true}]
    , attributes = {}
  }) {
  // console.log('Model.getTableName():', this.getTableName()); // article

  Object.keys(query_obj).forEach(key => {
    query_obj[key] = {
      [Op.like]: query_obj[key]
    }
  });
  Object.assign(query_obj, filter);

  // attributes.include ?
  //   attributes.include.push([sequelize.fn('COUNT', sequelize.col(`${this.options.name.singular}.id`)), 'count'])
  //   : (attributes.include = [[sequelize.fn('COUNT', sequelize.col(`${this.options.name.singular}.id`)), 'count']]);

  const rows = await this.findAll({
    attributes,
    where: query_obj,
    offset: (page_number - 1) * page_size,
    limit: page_size,
    order: order_by,
    include
  });

  const row = await this.findAll({
    // attributes:[]这种写法是要查询哪些字段
    // attributes:{}这种写法是默认包含所有字段你可以在里面配置要额外添加的聚合函数字段和排除的字段
    // ↓这种写法是只包含聚合函数字段
    attributes: [[sequelize.fn('COUNT', sequelize.col(`${this.options.name.singular}.id`)), 'count']]
  });

  const count = row[0].dataValues.count;
  const total_page = Math.ceil(count / page_size);
  return {rows, count, page_number, total_page}
};

module.exports = sequelize;
